JS 中 AMD、CMD、CommonJS、ES6 Module 的区别
AMD
AMD 一开始是 CommonJS 规范中的一个草案,全称是 Asynchronous Module Definition,即异步模块加载机制。后来由该草案的作者以 RequireJS 实现了 AMD 规范,所以一般说 AMD 也是指 RequireJS。
RequireJS 的基本用法
通过 define 来定义一个模块,使用 require 可以导入定义的模块。
RequireJS 的特点
对于依赖的模块,AMD 推崇依赖前置,提前执行。也就是说,在 define 方法里传入的依赖模块(数组),会在一开始就下载并执行。
CMD
CMD 是 SeaJS 在推广过程中生产的对模块定义的规范,在 Web 浏览器端的模块加载器中,SeaJS 与 RequireJS 并称,SeaJS 作者为阿里的玉伯。
SeaJS 的基本用法
SeaJS 的特点
对于依赖的模块,CMD 推崇依赖就近,延迟执行。也就是说,只有到 require 时依赖模块才执行。
CommonJS
CommonJS 规范为 CommonJS 小组所提出,目的是弥补 JavaScript 在服务器端缺少模块化机制,NodeJS、webpack 都是基于该规范来实现的。
CommonJS 的基本用法
CommonJS 的特点
所有代码都运行在模块作用域,不会污染全局作用域;
模块是同步加载的,即只有加载完成,才能执行后面的操作;
模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存;
require 返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值。
ES6 Module
ES6 Module 是 ES6 中规定的模块体系,相比上面提到的规范, ES6 Module 有更多的优势,有望成为浏览器和服务器通用的模块解决方案。
ES6 Module 的基本用法
ES6 Module 的特点(对比 CommonJS)
CommonJS 模块是运行时加载,ES6 Module 是编译时输出接口;
CommonJS 加载的是整个模块,将所有的接口全部加载进来,ES6 Module 可以单独加载其中的某个接口;
CommonJS 输出是值的拷贝,ES6 Module 输出的是值的引用,被输出模块的内部的改变会影响引用的改变;
CommonJS this 指向当前模块,ES6 Module this 指向 undefined;
目前浏览器对 ES6 Module 兼容还不太好,我们平时在 webpack 中使用的 export/import,会经过 babel 转换为 CommonJS 规范。
总结
这里比较全面的把 JavaScript 中的几大模块化规范罗列出来,希望借此对 JavaScript 模块化有一个大致的认识,而未对细节进行具体分析,感兴趣的可以自行探索。